package com.hsj.aop.jdk;


import com.hsj.aop.annoaop.Add;
import com.hsj.aop.annoaop.AddImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * 动态代理， 就是让 java自动去创建的代理对象，并且可以通过反射给所有方法进行增强，不需要每一个方法都写增强的内容，减少重复代码
 */
public class JDKDynamicProxy {

    //目标对象
    private AddImpl target;
    public JDKDynamicProxy(AddImpl target){
        this.target = target;
    }
    public Object getProxy(){
        /**
         * 参数1： ClassLoader 加载动态生成代理类的类加载器
         * 参数2： interfaces： 目标对象实现的接口类型，如果实现了多个接口，class类型的数组
         * 参数3： InvocationHandler: 设置代理对象实现目标对象方法的过程
         */
        ClassLoader classLoader = target.getClass().getClassLoader();
        Class<?>[] interfaces = target.getClass().getInterfaces();
        InvocationHandler invocationHandler = new InvocationHandler(){
            /**
             *   第一个参数  代理对象
             *   第二个参数  需要重写目标对象的方法
             *   第三个参数  method方法里面参数
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 //在方法调用之前增强
                System.out.println("动态代理 日志 "+method.getName()+"()方法 的 参数"+ Arrays.toString(args));
                //调用目标方法
                Object result = method.invoke(target, args);
                System.out.println("调用目标方法"+method.getName()+"成功");
                //在方法调用之后增强
                System.out.println("动态代理 日志 记录结束，返回值是"+result.toString());
                return result;
            }
        };

          return  Proxy.newProxyInstance(classLoader,interfaces,invocationHandler);
    }

    public static void main(String[] args) {

        //通过传入目标对象 创建代理对象
        JDKDynamicProxy jdkProxyAop = new JDKDynamicProxy(new AddImpl());
        Add proxy = (Add)jdkProxyAop.getProxy();
        proxy.add(1,2);
        proxy.sub(1,2);
    }
}


